<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Model_member extends CI_Model
{

    /**
     * 用户ID
     *
     * @access public
     * @var integer
     */
    public $uid = 0;

    /**
     * 用户昵称
     *
     * @access public
     * @var string
     */
    public $nick = '';


    /**
     * 初始化用户数据
     *
     * @access public
     * @return void
     */
    public function init()
    {
        $this->load->helper('cookie'); // 加载cookie辅助函数

        $auth = get_cookie('auth'); // 取出加密的auth字符串
        $auth = empty($auth) ? $this->input->post('auth') : $auth; // 接收POST形式的auth 用于swfupload
        if ( ! empty($auth))
        {
            $auth = $this->daddslashes(explode("\t", $this->authcode($auth, 'DECODE')));
            list($this->uid, $this->nick) = (empty($auth) || count($auth) < 2) ? array(0, '') : $auth;

            if ($this->uid)
            {
                $data = $this->get($this->uid); // 从数据库查询用户数据
                if (empty($data) OR $data['status']) // 用户不存在或用户被禁用
                {
                    $this->uid  = 0;
                    $this->nick = '';
                }
                else
                {
                    $this->uid  = intval($data['uid']);
                }
            }
        }
    }

    /**
     * 获取会员信息
     *
     * @access public
     * @param  integer $uid 会员ID
     * @return void
     */
    public function get($uid)
    {
        $this->load->database();

        $uid   = intval($uid);
        $query = $this->db->query("SELECT * FROM `tupian_member` WHERE `uid`={$uid} LIMIT 1");
        $rows  = $query->row_array();

        return $rows;
    }

    /**
     * 用户登录
     *
     * @access public
     * @param  string $openid  QQ的openid
     * @param  string $nick    QQ的昵称
     * @return void
     */
    public function login($openid, $nick)
    {
        $this->load->database();

        $query = $this->db->query("SELECT `uid` FROM `tupian_member` WHERE `open_id`='{$openid}' LIMIT 1");
        $rows  = $query->row_array();
        if (empty($rows))
        {
            $this->db->query("INSERT INTO `tupian_member` (`open_id`,`status`) VALUES ('{$openid}',0)");
            $rows['uid'] = $this->db->insert_id();
        }

        $this->load->helper('cookie');
        set_cookie('auth', $this->authcode("{$rows['uid']}\t{$nick}", 'ENCODE'), 86400);
    }

    /**
     * 用户退出
     *
     * @access public
     * @return void
     */
    public function logout()
    {
        $this->load->helper('cookie');
        delete_cookie('auth');
    }

    /**
     * 检查用户是否登录
     *
     * 已登录返回TRUE 没有登录返回FALSE
     *
     * @access public
     * @return boolean
     */
	public function is_login()
	{
        if (empty($this->uid))
        {
            return FALSE;
        }

        return TRUE;
	}

    public function is_admin()
    {
        if ($this->uid == 1)
        {
            return TRUE;
        }

        return FAlSE;
    }

    public function goto_login()
    {
        $this->load->helper('url');
        redirect($this->config->item('base_url') . '/' . $this->config->item('index_page'));
    }

    public function goto_album()
    {
        $this->load->helper('url');
        redirect($this->config->item('base_url') . '/' . $this->config->item('index_page') . '?c=album');
    }

    public function get_qq_access_token($code)
    {
        $url  = 'https://graph.qq.com/oauth2.0/token?grant_type=authorization_code'
              . '&client_id=' . $this->config->item('qq_appid')
              . '&client_secret=' . $this->config->item('qq_appsecret')
              . '&redirect_uri=' . urlencode($this->get_qq_callback())
              . '&code=' . $code;

        $response = $this->get_url_contents($url);
        $response = $this->get_api_response($response);

        return $response;
    }

    public function get_qq_openid($token)
    {
        $url   = 'https://graph.qq.com/oauth2.0/me?access_token=' . $token;
        $response = $this->get_url_contents($url);
        $response = $this->get_api_response($response);

        return $response;
    }

    public function get_qq_user_info($token, $openid)
    {
        $url    = 'https://graph.qq.com/user/get_user_info?access_token=' . $token
                . '&oauth_consumer_key=' . $this->config->item('qq_appid')
                . '&openid=' . $openid;
        $response = $this->member->get_url_contents($url);
        $response = json_decode($response, TRUE);

        return $response;
    }

    public function get_qq_callback()
    {
        return $this->config->item('base_url') . '/' . $this->config->item('index_page') . '?c=member&m=callback';
    }

    public function get_url_contents($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);

        if (ENVIRONMENT == 'development')
        {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        }

        $result =  curl_exec($ch);

        curl_close($ch);

        return $result;
    }

    public function get_api_response($response)
    {
        $params = array();

        if (strpos($response, "callback") !== FALSE)
        {
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response  = substr($response, $lpos + 1, $rpos - $lpos -1);
            $json = json_decode($response);
            if (isset($json->error))
            {
                $params = array('error_code' => $json->error, 'msg' => $json->error_description);
            }
            elseif (isset($json->openid))
            {
                $params = array('error_code' => 0, 'msg' => 'ok' , 'openid' => $json->openid);
            }
        }
        else
        {
            parse_str($response, $params);
            $params['msg'] = 'ok';
            $params['error_code'] = 0;
        }

        return $params;
    }

    /**
     * 加密和解密函数
     *
     * <code>
     * // 加密用户ID和用户名
     * $auth = authcode("{$uid}\t{$username}", 'ENCODE');
     * // 解密用户ID和用户名
     * list($uid, $username) = explode("\t", authcode($auth, 'DECODE'));
     * </code>
     *
     * @access public
     * @param  string  $string    需要加密或解密的字符串
     * @param  string  $operation 默认是DECODE即解密 ENCODE是加密
     * @param  string  $key       加密或解密的密钥 参数为空的情况下取全局配置encryption_key
     * @param  integer $expiry    加密的有效期(秒)0是永久有效 注意这个参数不需要传时间戳
     * @return string
     */
    public function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
    {
        $ckey_length = 4;
        $key  = md5($key != '' ? $key : config_item('encryption_key'));
        $keya = md5(substr($key, 0, 16));
        $keyb = md5(substr($key, 16, 16));
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

        $cryptkey = $keya . md5($keya . $keyc);
        $key_length = strlen($cryptkey);

        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0)
                . substr(md5($string . $keyb), 0, 16)
                . $string;
        $string_length = strlen($string);

        $result = '';
        $box = range(0, 255);

        $rndkey = array();
        for ($i = 0; $i <= 255; $i++)
        {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }

        for ($j = $i = 0; $i < 256; $i++)
        {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }

        for ($a = $j = $i = 0; $i < $string_length; $i++)
        {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }

        if ($operation == 'DECODE')
        {
            if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16))
            {
                return substr($result, 26);
            }
            else
            {
                return '';
            }
        }
        else
        {
            return $keyc . str_replace('=', '', base64_encode($result));
        }
    }

    /**
     * 使用反斜线引用字符串(支持数组格式)
     *
     * @access public
     * @param  array|string  $string
     * @param  integer       $force
     * @return array|string
     */
    public function daddslashes($string, $force = 1)
    {
        if (is_array($string))
        {
            foreach ($string as $key => $val)
            {
                unset($string[$key]);
                $string[addslashes($key)] = $this->daddslashes($val, $force);
            }
        }
        else
        {
            $string = addslashes($string);
        }

        return $string;
    }
}